﻿namespace BM.Tools.WebControls.MForm.Design
{
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Globalization;
    using System.Web.UI;
    using System.Web.UI.Design;
    using System.Web.UI.Design.WebControls;

    /// <summary>
    /// This is a control designer for a control with only one <see cref="ITemplate" />.
    /// </summary>
    public abstract class SingleTemplateControlDesigner : CompositeControlDesigner
    {
        /// <summary>
        /// Gets CurrentTemplate.
        /// </summary>
        protected abstract ITemplate CurrentTemplate
        {
            get;
        }

        /// <summary>
        /// Gets the editable region description.
        /// </summary>
        protected virtual string EditableRegionDescription
        {
            get
            {
                return TemplatePropertyName;
            }
        }

        /// <summary>
        /// Gets the template definition name.
        /// </summary>        
        protected virtual string TemplateDefinitionName
        {
            get
            {
                return TemplatePropertyName;
            }
        }

        /// <summary>
        /// Gets the template property name.
        /// </summary>        
        protected abstract string TemplatePropertyName
        {
            get;
        }

        /// <summary>
        /// Gets the current template descriptor.
        /// </summary>        
        private PropertyDescriptor CurrentTemplateDescriptor
        {
            get
            {
                return TypeDescriptor.GetProperties(Component)[TemplatePropertyName];
            }
        }

        /// <summary>
        /// Gets the template definition.
        /// </summary>        
        private TemplateDefinition TemplateDefinition
        {
            get
            {
                return new TemplateDefinition(this, TemplateDefinitionName, Component, TemplatePropertyName);
            }
        }

        /// <summary>
        /// Retrieves the HTML markup to display the control and populates the collection with the current control designer regions.
        /// </summary>
        /// <returns>
        /// The design-time HTML markup for the associated control, including all control designer regions.
        /// </returns>
        /// <param name="regions">
        /// A collection of control designer regions for the associated control.
        /// </param>
        public override string GetDesignTimeHtml(DesignerRegionCollection regions)
        {
            if (regions == null)
            {
                return base.GetDesignTimeHtml(regions);
            }

            EditableDesignerRegion region = new SingleTemplateControlDesignerRegion(
                    Component, CurrentTemplate, CurrentTemplateDescriptor, TemplateDefinition);
            region.Description = EditableRegionDescription;
            regions.Add(region);
            string contentAttributes = string.Format(
                    CultureInfo.InvariantCulture,
                    " nowrap style=\"border-top:1px solid #CCCCCC;padding: 1px; vertical-align:top; height: 100%\" {0}=\"0\"",
                    new object[] { DesignerRegion.DesignerRegionAttributeName });
            return GetContainerDesignTimeHtml(string.Empty, contentAttributes);
        }

        /// <summary>
        /// Returns the content for an editable region of the design-time view of the associated control.
        /// </summary>
        /// <returns>
        /// The persisted content for the region, if the control designer supports editable regions; otherwise, an empty string ("").
        /// </returns>
        /// <param name="region">
        /// The <see cref="T:System.Web.UI.Design.EditableDesignerRegion"/> to get content for.
        /// </param>
        public override string GetEditableDesignerRegionContent(EditableDesignerRegion region)
        {
            var region2 = region as SingleTemplateControlDesignerRegion;
            if (region2 != null)
            {
                ITemplate template = region2.Template;
                if (template != null)
                {
                    var service = (IDesignerHost)Component.Site.GetService(typeof(IDesignerHost));
                    return ControlPersister.PersistTemplate(template, service);
                }
            }

            return base.GetEditableDesignerRegionContent(region);
        }

        /// <summary>
        /// Specifies the content for an editable region of the control at design time. 
        /// </summary>
        /// <param name="region">An editable design region contained within the control.</param><param name="content">The content to assign for the editable design region.</param>
        public override void SetEditableDesignerRegionContent(EditableDesignerRegion region, string content)
        {
            var region2 = region as SingleTemplateControlDesignerRegion;
            if (region2 != null)
            {
                var service = (IDesignerHost)Component.Site.GetService(typeof(IDesignerHost));
                ITemplate template = ControlParser.ParseTemplate(service, content);
                region2.PropertyDescriptor.SetValue(region2.Component, template);
                region2.Template = template;
            }
        }

        private static string GetContainerDesignTimeHtml(string content, string contentAttributes)
        {
            string str4 = string.Empty;
            if (!string.IsNullOrEmpty(content) || !string.IsNullOrEmpty(contentAttributes))
            {
                str4 = string.Format(
                        CultureInfo.InvariantCulture,
                        "\r\n<tr>\r\n<td {1}>{0}</td>\r\n</tr>\r\n",
                        new object[] { content, contentAttributes });
            }

            return string.Format(
                    CultureInfo.InvariantCulture,
                    "<table style=\"border:1px solid #CCCCCC;\" width=\"100%\" cellspacing=\"3\" cellpadding=\"3\">{0}</table>",
                    str4);
        }
    }
}